package main

import (
	"context"
	"fmt"
	"github.com/gorilla/mux"
	"google.golang.org/grpc"
	"log"
	"net/http"
	"share-grpc/pb"
	"share-grpc/resolver"
	"strconv"
)

var router = mux.NewRouter()

const etcdHost = "etcd:2379"

func handlerRegisterFunc(w http.ResponseWriter, r *http.Request) {
	err := r.ParseForm()
	if err != nil {
		fmt.Fprint(w, "缺少参数")
		return
	}

	// etcd 发现服务
	cli, _ := resolver.NewClient([]string{etcdHost})
	services, _ := cli.GetService("vector_rpc_server")

	// 链接已经注册到 etcd 的微服务，这里使用的是单机的etcd，取数组的第一个值即可
	conn, err := grpc.Dial(services[0], grpc.WithInsecure(), grpc.WithBlock())
	if err != nil {
		log.Println("无法链接微服务: ", err)
		fmt.Fprint(w, "无法链接微服务")
		return
	}
	defer conn.Close()

	user := pb.User{}
	user.Username = r.PostForm.Get("username")
	user.Password = r.PostForm.Get("password")
	user.Email = r.PostForm.Get("email")
	aUser := pb.RegisterRequest{User: &user}

	// 调用 *.pb.go中的 New*Client 方法
	client := pb.NewUserCenterClient(conn)
	result, err := client.Register(context.Background(), &aUser) // 调用该微服务下的 Register 方法
	if err != nil {
		fmt.Fprint(w, "无法调用微服务")
		return
	}

	lastInsertID := result.UserId

	if lastInsertID > 0 {
		fmt.Fprint(w, "注册新用户成功，用户Id："+strconv.FormatInt(lastInsertID, 10)+"，用户名："+user.Username)
	} else {
		checkError(err)
		w.WriteHeader(http.StatusInternalServerError)
		fmt.Fprint(w, "500 服务器内部错误")
	}
}

func handlerLoginFunc(w http.ResponseWriter, r *http.Request) {
	err := r.ParseForm()
	checkError(err)

	username := r.PostForm.Get("username")
	password := r.PostForm.Get("password")

	fmt.Fprint(w, "这是登录接口,登录用户："+username+", 登录密码："+password)
}

func main() {
	log.Println("程序准备启动")
	router.HandleFunc("/", handlerFunc).Methods("GET").Name("home")

	// 注册
	router.HandleFunc("/users/register", handlerRegisterFunc).Methods("POST").Name("users.register")
	// 登录
	router.HandleFunc("/users/login", handlerLoginFunc).Methods("POST").Name("users.login")

	// 自定义 404 页面
	router.NotFoundHandler = http.HandlerFunc(notFoundHandler)

	// 中间件：强制内容类型为 HTML
	router.Use(forceJsonMiddleware)

	http.ListenAndServe(":3000", router)
}

func handlerFunc(w http.ResponseWriter, r *http.Request) {
	fmt.Fprint(w, "Hello World")
}

func notFoundHandler(w http.ResponseWriter, r *http.Request) {
	w.WriteHeader(http.StatusNotFound)
	fmt.Fprint(w, "请求页面未找到")
}

func forceJsonMiddleware(next http.Handler) http.Handler {
	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		// 1. 设置标头
		w.Header().Set("Content-Type", "application/json; charset=utf-8")
		// 2. 继续处理请求
		next.ServeHTTP(w, r)
	})
}

func checkError(err error) {
	if err != nil {
		log.Fatal(err)
	}
}
